package controller

import (
	"coursedesign/projectGo/common"
	"coursedesign/projectGo/model"
	"coursedesign/projectGo/response"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"gorm.io/gorm"
	"strconv"
	"unicode"
)

type IEnterController interface {
	RestController
}

type EnterController struct {
	DB *gorm.DB
}

func NewEnterController() IEnterController {
	db := common.GetDB()
	return EnterController{DB: db}
}

func (e EnterController) Create(c *gin.Context) {
	var re model.EnterAPI
	c.ShouldBindJSON(&re)
	fmt.Println(re)
	create := model.Enter{
		Sid:      re.Sid,
		Cid:      re.Cid,
		Name:     re.Name,
		Carid:    re.Carid,
		Edate:    re.Edate,
		Quantity: re.Quantity,
		Quality:  re.Quality,
	}
	// 查看货物名是否为空
	length := len(re.Name)
	flag := 0
	for i := 0; i<length; i++ {
		if unicode.IsSpace(rune(re.Name[i])) {
			flag += 1
		} else {
			break
		}
	}
	if flag == length {
		response.Fail(c, "货物名不可为空", nil)
		return
	}
	// 查询公司是否存在
	if e.DB.Model(&model.Company{}).Where("id=?", re.Cid).
		Find(&model.Company{}).RowsAffected == 0 {
		response.Fail(c, "查无此公司", nil)
		return
	}
	// 判断吨数是否正常
	if create.Quality<=0 || create.Quantity<=0 {
		response.Fail(c, "货物件数/吨数不可为0", nil)
		return
	}
	// 判断货物是否已存在
	sqlWords := "sid=? and cid=? and name=? and carid=? and edate=?"
	result := e.DB.Model(&model.Enter{}).Where(sqlWords, create.Sid, create.Cid, create.Name,
		create.Carid, create.Edate).Find(&model.Enter{}).RowsAffected
	if result != 0 {
		response.Fail(c, "货物已入库", nil)
		return
	}
	// 判断仓库状态
	var store model.Store
	e.DB.Model(&model.Store{}).Where("id=?", create.Sid).Find(&store)
	if store.Status == "满" {
		response.Fail(c, "仓库已满，请选择其他仓库", nil)
		return
	}
	// 创建
	create.UUID = uuid.New()
	err := e.DB.Model(&model.Enter{}).Create(&create).Error
	if err != nil {
		response.Fail(c, err.Error(), nil)
		return
	}
	response.Success(c, gin.H{"enter": create}, "创建成功")
}

func (e EnterController) Update(c *gin.Context) {
	// 绑定body中参数（更新后的值）
	var re model.EnterAPI
	c.ShouldBind(&re)
	// 判断吨数是否合理
	if re.Quality<=0 || re.Quantity<=0 {
		response.Fail(c, "货物件数/吨数不可为0", nil)
		return
	}
	// 查看货物名是否为空
	length := len(re.Name)
	flag := 0
	for i := 0; i<length; i++ {
		if unicode.IsSpace(rune(re.Name[i])) {
			flag += 1
		} else {
			break
		}
	}
	if flag == length {
		response.Fail(c, "货物名不可为空", nil)
		return
	}

	uid := c.Param("uuid")
	u, _ := uuid.Parse(uid)
	update := model.Enter{
		UUID:          u,
		Sid:           re.Sid,
		Cid:           re.Cid,
		Name:          re.Name,
		Carid:         re.Carid,
		Edate:         re.Edate,
		Quantity:      re.Quantity,
		Quality:       re.Quality,
	}
	var store model.Store
	e.DB.Model(&model.Store{}).Where("id=?", update.Sid).Find(&store)
	if store.Status == "满" {
		response.Fail(c, "仓库已满，请选择其他仓库", nil)
		return
	}
	// 吨数改，剩余吨数改
	var beforeUpdate model.Enter
	e.DB.Model(&model.Enter{}).Where("uuid=?", u).First(&beforeUpdate)
	update.RemainQuality = beforeUpdate.RemainQuality + (update.Quality - beforeUpdate.Quality)
	/*
	// 日期改，堆存费改
	var beforeUpdate model.Enter
	err := e.DB.Model(&model.Enter{}).Where("uuid=?", u.String()).Find(&beforeUpdate).Error
	if err != nil {
		response.Fail(c, err.Error(), nil)
		return
	}
	if beforeUpdate.Edate != update.Edate {
		var delivers []model.Deliver
		e.DB.Model(&model.Deliver{}).Where("?=ANY(enterid)", u).Find(&delivers)
		for i:=0; i<len(delivers); i++ {
			updateDate := beforeUpdate.Edate.Sub(update.Edate).Hours() / 24
			subHours := delivers[i].Ddate.Sub(update.Edate).Hours()
			subDays := subHours / 24
			if subDays >= 14 {
				delivers[i].Fee += (subDays - 13) * update.Quality * 0.5
			}
		}
	}
	 */
	// 更新
	err := e.DB.Model(&model.Enter{}).Where("uuid=?", u.String()).Updates(&update).Error
	if err != nil {
		response.Fail(c, err.Error(), nil)
		return
	}
	response.Success(c, gin.H{"enter": update}, "修改成功")
}

func (e EnterController) Delete(c *gin.Context) {
	// 删除
	u, _ := uuid.Parse(c.Params.ByName("uuid"))
	err := e.DB.Model(&model.Enter{}).Where("uuid=?", u).Delete(&model.Enter{}).Error
	if err != nil {
		response.Fail(c, err.Error(), nil)
		return
	}
	response.Success(c, nil, "删除成功")
}

func (e EnterController) PageList(c *gin.Context) {
	cid, _ := c.GetQuery("cid")
	var selectEnter []model.Enter
	if cid != "" {
		// 查询
		err := e.DB.Model(&model.Enter{}).Where("cid=?", cid).
			Find(&selectEnter).Error
		if err != nil {
			response.Fail(c, err.Error(), nil)
			return
		}
		response.Success(c, gin.H{"enter": selectEnter}, "查询成功")
		return
	}
	// 获取分页参数
	tempNum, _ := c.GetQuery("pagenum")
	tempSize, _ := c.GetQuery("pagesize")
	pageNum, _ := strconv.Atoi(tempNum)   // 当前页数
	pageSize, _ := strconv.Atoi(tempSize) // 页内个数
	if pageNum == 0 {
		pageNum = 1
	}
	if pageSize == 0 {
		pageSize = 10
	}
	// 分页
	e.DB.Order("edate ASC").Offset((pageNum - 1) * pageSize).Limit(pageSize).Find(&selectEnter)

	// 前端渲染分页也要知道总数
	var total int64
	e.DB.Model(model.Enter{}).Count(&total)

	response.Success(c, gin.H{"data": selectEnter, "total": total}, "查询成功")
}
